import keyboard
import pygame
import random
import math
from settings import *
from arrow import Arrow
from utils import dialog_get_mode, dialog_showinfo


class Game:
    def __init__(self, screen):
        self.screen = screen
        self.clock = pygame.time.Clock()
        self.arrows = []
        self.player_arrow = None
        self.move_speed = MOVE_SPEEDS['base']  # 使用配置的基础速度
        self.candidate_positions = []
        self._init_game()
        self.highlight_phase = 0  # 新增：红圈显示阶段
        self.highlight_timer = 0  # 新增：红圈计时器
        self.auto_move_timer = 0  # 新增：自动移动计时器
        self.auto_move_triggered = False  # 新增：是否已触发自动移动
        self.control_disabled = False
        self.control_disabled_timer = 0
        self.highlight_groups = [[], []]  # 存储两组箭头
        self.highlight_event_posted = False  # 新增：标记是否已设置红圈事件
        self.move_event_posted = False  # 新增：标记是否已设置移动事件
        self.fail_message = ""  # 新增：失败提示信息
        self.font = pygame.font.SysFont(None, FONT_CONFIG['size'], bold=FONT_CONFIG['bold'])
        self.fail_timer = 0  # 新增：提示显示计时器
        self.player_group = None  # 记录玩家所在组别

        self.waiting_for_judgment = False  # 新增：等待判定状态
        self.judgment_arrow = None  # 待判定的箭头
        self.user_success_group = {"hongquan": -2, "chengshang": -2}  # 用户承伤记录红圈和承伤
        self.result_message = ""
        self.result_color = (0, 0, 0)
        self.result_timer = 0  # 新增初始化

        self.result_message = ""
        self.result_color = (0, 0, 0)
        self.result_timer = 0
        self._init_font_system()
        self._mode = 0  # 默认是常规模式0  ；逃课模式：1
        dialog_showinfo()
        keyboard.press_and_release("shift")  # 临时切换中英文

    def _init_font_system(self):
        """多级字体加载系统"""
        font_paths = [
            # 1. 尝试项目字体目录
            os.path.join(os.path.dirname(__file__), 'fonts/simhei.ttf'),
            # 2. 尝试Windows系统字体
            'C:/Windows/Fonts/simhei.ttf',
            # 3. 尝试其他常见中文字体
            'C:/Windows/Fonts/msyh.ttc',  # 微软雅黑
            'C:/Windows/Fonts/simfang.ttf'  # 仿宋
        ]

        for path in font_paths:
            try:
                self.font = pygame.font.Font(path, FONT_CONFIG['size'])
                if FONT_CONFIG['bold']:
                    self.font.set_bold(True)
                return
            except Exception as e:
                continue

        # 最终回退方案
        self.font = pygame.font.SysFont('arial', FONT_CONFIG['size'], bold=True)

    def _check_in_circle(self, arrow, radius=YELLOW_CIRCLE_RADIUS):
        """检查箭头是否在黄圈内"""
        dx = arrow.x - WIDTH // 2
        dy = arrow.y - HEIGHT // 2
        distance = math.sqrt(dx ** 2 + dy ** 2)
        return distance <= radius

    def _randomize_groups(self):
        """随机分组（每个方向选1个到第一组）"""
        dir_groups = {}
        for arrow in self.arrows:
            if arrow.direction not in dir_groups:
                dir_groups[arrow.direction] = []
            dir_groups[arrow.direction].append(arrow)

        self.highlight_groups = [[], []]
        for dir, arrows in dir_groups.items():
            chosen = random.choice(arrows)
            self.highlight_groups[0].append(chosen)
            self.highlight_groups[1].extend([a for a in arrows if a != chosen])

    def _init_game(self):
        """初始化游戏状态"""
        # 随机选择方向组合：偶数组或奇数组
        self.current_directions = random.choice([[0, 2, 4, 6], [1, 3, 5, 7]])
        self._create_arrows()
        self._create_candidate_positions()

    def _create_candidate_positions(self):
        """创建备选位置"""
        self.candidate_positions = []

        # 根据当前方向组确定备选位置角度
        if self.current_directions == [0, 2, 4, 6]:  # 正方位
            angles = [90, 270, 0, 180]  # 与箭头方向垂直的四个方位
        else:  # 偏方位
            angles = [45, 225, 135, 315]  # 与箭头方向垂直的四个偏方位

        # 创建内圈和外圈备选位置
        for angle in angles:
            # 内圈位置
            inner_x = WIDTH // 2 + CANDIDATE_RADII['inner'] * math.cos(math.radians(angle))
            inner_y = HEIGHT // 2 + CANDIDATE_RADII['inner'] * math.sin(math.radians(angle))
            self.candidate_positions.append(('inner', inner_x, inner_y, angle))

            # 中圈位置
            outer_x = WIDTH // 2 + CANDIDATE_RADII['median1'] * math.cos(math.radians(angle))
            outer_y = HEIGHT // 2 + CANDIDATE_RADII['median1'] * math.sin(math.radians(angle))
            self.candidate_positions.append(('median1', outer_x, outer_y, angle))

            # 中圈位置
            outer_x = WIDTH // 2 + CANDIDATE_RADII['median2'] * math.cos(math.radians(angle))
            outer_y = HEIGHT // 2 + CANDIDATE_RADII['median2'] * math.sin(math.radians(angle))
            self.candidate_positions.append(('median2', outer_x, outer_y, angle))

            # 外圈位置
            outer_x = WIDTH // 2 + CANDIDATE_RADII['outer'] * math.cos(math.radians(angle))
            outer_y = HEIGHT // 2 + CANDIDATE_RADII['outer'] * math.sin(math.radians(angle))
            self.candidate_positions.append(('outer', outer_x, outer_y, angle))

    def _create_arrows(self):
        """创建所有箭头"""
        # 初始化方向计数
        direction_counts = {d: 0 for d in self.current_directions}

        # 创建7个固定箭头
        for _ in range(7):
            # 获取可用方向（每个方向最多2个箭头）
            available_directions = [
                d for d in self.current_directions
                if direction_counts[d] < 2
            ]
            if not available_directions:
                break

            # 随机选择一个可用方向
            direction = random.choice(available_directions)
            direction_counts[direction] += 1

            # 在黄圈内随机生成位置
            angle = math.radians(direction * 45 + random.uniform(-15, 15))
            r = YELLOW_CIRCLE_RADIUS * random.uniform(0.4, 0.8)

            x = WIDTH // 2 + r * math.cos(angle)
            y = HEIGHT // 2 + r * math.sin(angle)

            # 创建箭头并添加到列表
            arrow = Arrow(x, y, direction)
            self.arrows.append(arrow)

        # 创建玩家箭头（使用剩余方向）
        player_direction = [
            d for d in self.current_directions
            if direction_counts[d] < 2
        ][0]
        self.player_arrow = Arrow(WIDTH // 2, HEIGHT // 2, player_direction, is_player=True)
        self.player_arrow.reg_move_event(pygame.USEREVENT + 2, pygame.USEREVENT + 3)
        self.arrows.append(self.player_arrow)

    def draw_candidates(self):
        """绘制备选位置（深蓝色圆环）"""
        for pos_type, x, y, angle in self.candidate_positions:
            pygame.draw.circle(
                self.screen,
                CANDIDATE_COLORS[pos_type],
                (int(x), int(y)),
                CANDIDATE_SIZE,
                2  # 线宽2像素的圆环
            )

    def start_red_circle(self):
        # 触发红圈显示（原有逻辑）
        self.trigger_highlight()

    def switch_npc_arrow_visitable(self):
        for arrow in self.arrows:
            if not arrow.is_player:
                arrow.visitable = not arrow.visitable

    def set_player_dashed_line(self):
        original_x = WIDTH // 2
        original_y = HEIGHT // 2
        self.player_arrow.set_dashed_point([original_x, original_y])
        self.player_arrow.set_show_dashed_line(True)

    def handle_events(self):
        """处理所有输入事件和状态检测"""
        for event in pygame.event.get():
            # 退出事件
            if event.type == pygame.QUIT:
                return False

            # 按键按下事件
            elif event.type == pygame.KEYDOWN:

                # T键触发承伤检测和红圈显示
                if event.key == pygame.K_t:
                    # 承伤检测（仅判断玩家箭头）
                    self.result_message = "进行中"
                    self.result_color = (0, 0, 0)
                    self.result_timer = RESULT_CONFIG['duration']

                    # 触发红圈显示（原有逻辑）
                    self.trigger_highlight()
                    self.set_player_dashed_line()

                elif event.key == pygame.K_F1:
                    dialog_showinfo()
                elif event.key == pygame.K_F2:
                    self._mode = dialog_get_mode()
                elif event.key == pygame.K_h:
                    self.switch_npc_arrow_visitable()

            elif event.type == pygame.USEREVENT:  # 第二组红圈
                for arrow in self.highlight_groups[1]:
                    arrow.start_highlight(HIGHLIGHT_DURATION)
                self._npc_arrow_move_candidates()


            elif event.type == pygame.USEREVENT + 1:  # 自动移动
                self.control_disabled = True
                self._trigger_auto_move()
                self.player_arrow.set_show_dashed_line(False)

            elif event.type == pygame.USEREVENT + 2:  # 用户控体开始移动(箭头类触发）
                self.control_disabled = True
                self.process_user_move_begin()

            elif event.type == pygame.USEREVENT + 3:  # 用户控体移动结束(箭头类触发）
                self.process_user_move_finished()
                self.control_disabled = False

            elif event.type == pygame.USEREVENT + 4:  # 承伤结果判断
                self._judge_result()

        # 持续按键检测（WASD移动，非禁用状态）
        if not self.control_disabled:
            keys = pygame.key.get_pressed()
            if keys[pygame.K_w]:
                self.player_arrow.move(0, -MOVE_SPEEDS['base'])
            if keys[pygame.K_s]:
                self.player_arrow.move(0, MOVE_SPEEDS['base'])
            if keys[pygame.K_a]:
                self.player_arrow.move(-MOVE_SPEEDS['base'], 0)
            if keys[pygame.K_d]:
                self.player_arrow.move(MOVE_SPEEDS['base'], 0)

        return True

    # 常规判断
    def judge_begin_in_normal_mode(self):
        another_group = self.highlight_groups[0]
        if self.player_arrow in self.highlight_groups[0]:
            # 用户是第一组
            self._on_user_dont_in_circle()
            another_group = self.highlight_groups[1]
        else:
            # 用户是第二组
            self._on_user_need_in_circle()

        # 与另一组的箭头少于6尺 —— 失败
        for arrow in another_group:
            if not arrow.is_player and self.calc_distance_by_arrow(self.player_arrow, arrow) < XR_RADIUS:
                self.user_success_group["hongquan"] = False

    def judge_finished_in_normal_mode(self):
        another_group = self.highlight_groups[0]
        if self.player_arrow in self.highlight_groups[0]:
            # 用户是第一组
            self._on_user_need_in_circle()
            another_group = self.highlight_groups[1]
        else:
            # 用户是第二组
            self._on_user_dont_in_circle()
        # 与另一组的箭头少于6尺 —— 失败
        for arrow in another_group:
            if not arrow.is_player and self.calc_distance_by_arrow(self.player_arrow, arrow) < XR_RADIUS:
                self.user_success_group["hongquan"] = False

    def calc_distance_by_arrow(self, arrow1, arrow2):
        dx = arrow1.x - arrow2.x
        dy = arrow1.y - arrow2.y
        return math.sqrt(dx ** 2 + dy ** 2)

    # 逃课判断
    def judge_begin_in_simple_mode(self):
        """ 1、在圈里   2、不吃第一波的圈 """
        in_circle = self._check_in_circle(self.player_arrow)
        self.user_success_group["chengshang"] = in_circle

        # 与第一组的箭头少于6尺 —— 失败
        for arrow in self.highlight_groups[0]:
            if not arrow.is_player and self.calc_distance_by_arrow(self.player_arrow, arrow) < XR_RADIUS:
                self.user_success_group["chengshang"] = False

        print(f"承伤：{self.user_success_group["chengshang"]}")
        if self.user_success_group["hongquan"] > -2:
            pygame.time.set_timer(pygame.USEREVENT + 4, 1, 1)

    def judge_finished_in_simple_mode(self):
        """ 1、在圈里   2、不吃第二波的圈 """
        in_circle = self._check_in_circle(self.player_arrow)
        self.user_success_group["hongquan"] = in_circle

        # 与第二组的箭头少于6尺 —— 失败
        for arrow in self.highlight_groups[1]:
            if not arrow.is_player and self.calc_distance_by_arrow(self.player_arrow, arrow) < XR_RADIUS:
                self.user_success_group["hongquan"] = False

        print(f"承伤：{self.user_success_group["hongquan"]}")
        if self.user_success_group["chengshang"] > -2:
            pygame.time.set_timer(pygame.USEREVENT + 4, 1, 1)

    def process_user_move_begin(self):
        if self._mode == 0:
            self.judge_begin_in_normal_mode()
        elif self._mode == 1:
            self.judge_begin_in_simple_mode()

    def process_user_move_finished(self):
        if self._mode == 0:
            self.judge_finished_in_normal_mode()
        elif self._mode == 1:
            self.judge_finished_in_simple_mode()

    def _on_user_need_in_circle(self):
        """用户承伤时机"""
        in_circle = self._check_in_circle(self.player_arrow)
        self.user_success_group["chengshang"] = in_circle
        print(f"承伤：{self.user_success_group["chengshang"]}")
        if self.user_success_group["hongquan"] > -2:
            pygame.time.set_timer(pygame.USEREVENT + 4, 1, 1)

    def _on_user_need_in_circle_2(self):
        """用户承伤时机"""
        in_circle = self._check_in_circle(self.player_arrow)
        self.user_success_group["hongquan"] = in_circle
        print(f"承伤：{self.user_success_group["hongquan"]}")
        if self.user_success_group["chengshang"] > -2:
            pygame.time.set_timer(pygame.USEREVENT + 4, 1, 1)

    def _on_user_dont_in_circle(self):
        """用户红圈消失时的处理"""
        in_circle = self._check_in_circle(self.player_arrow)
        is_success = not in_circle  # 圈外=成功
        self.user_success_group["hongquan"] = is_success
        print(f"红圈：{is_success}")
        if self.user_success_group["chengshang"] > -2:
            pygame.time.set_timer(pygame.USEREVENT + 4, 1, 1)

    def _judge_result(self):
        if self.user_success_group["chengshang"] and self.user_success_group["hongquan"]:
            self._show_result(True)
        else:
            self._show_result(False)

        self.control_disabled = False
        self.user_success_group["chengshang"] = -2
        self.user_success_group["hongquan"] = -2

    # npc箭头移动到备选位置
    def _npc_arrow_move_candidates(self):
        for arrow in self.arrows:
            if arrow.is_player:
                continue
            if self._mode == 0:
                # 常规控体
                if arrow in self.highlight_groups[0]:
                    # 是第一组
                    arrow.goto_with_scale_polar(17, -1 * (90 + arrow.rotation))
                else:
                    # 是第二组
                    arrow.goto_with_scale_polar(9, (90 - arrow.rotation))
            elif self._mode == 1:
                # 逃课控体
                if arrow in self.highlight_groups[0]:
                    # 是第一组
                    arrow.goto_with_scale_polar(9, -1 * (90 + arrow.rotation))
                else:
                    # 是第二组
                    arrow.goto_with_scale_polar(2, -1 * (90 + arrow.rotation))

    def _trigger_auto_move(self):
        """执行自动移动"""
        self.control_disabled = True
        self.control_disabled_timer = MOVE_DURATION * 60

        # 移动所有箭头
        for arrow in self.arrows:
            arrow.lock_movement()
            arrow.start_movement()

        print("自动移动已触发")  # 调试输出

    def trigger_highlight(self):
        """完整的红圈+自动移动触发"""
        self._randomize_groups()

        # 1. 显示第一组红圈
        for arrow in self.highlight_groups[0]:
            arrow.start_highlight(HIGHLIGHT_DURATION)

        # 2. 延迟显示第二组红圈（2秒后）
        pygame.time.set_timer(
            pygame.USEREVENT,
            int(HIGHLIGHT_PHASE_DELAY * 1000),
            1
        )

        # 3. 触发自动移动（6秒后）
        pygame.time.set_timer(
            pygame.USEREVENT + 1,
            int(AUTO_MOVE_DELAY * 1000),
            1
        )

    def _show_result(self, is_success):
        """显示判定结果"""
        self.result_message = "承伤成功" if is_success else "承伤失败"
        self.result_color = RESULT_CONFIG['colors']['success' if is_success else 'fail']
        self.result_timer = RESULT_CONFIG['duration']

    def _select_one_per_direction(self):
        """每个方向选择1个箭头"""
        selected = []
        directions = set(arrow.direction for arrow in self.arrows)

        for direction in directions:
            # 获取该方向的所有箭头
            arrows_in_dir = [a for a in self.arrows if a.direction == direction]
            if arrows_in_dir:
                # 随机选择1个
                selected.append(random.choice(arrows_in_dir))

        return selected

    def update(self):
        for arrow in self.arrows:
            if arrow.should_highlight and arrow.highlight_timer <= 5:  # 最后5帧
                self.judgment_arrow = arrow
                self.waiting_for_judgment = True

        # 更新提示计时器
        if self.result_timer > 0:
            self.result_timer -= 1
            if self.result_timer <= 0:
                self.result_message = ""

        # 清除事件计时器（避免重复触发）
        pygame.event.clear(pygame.USEREVENT)
        pygame.event.clear(pygame.USEREVENT + 1)
        pygame.event.clear(pygame.USEREVENT + 2)
        pygame.event.clear(pygame.USEREVENT + 3)
        pygame.event.clear(pygame.USEREVENT + 4)
        # 红圈阶段更新
        if self.highlight_phase == 1:
            self.highlight_timer -= 1
            if self.highlight_timer <= 0:
                self.highlight_phase = 2
                # 显示第二组
                first_group = self._select_one_per_direction()
                for arrow in self.arrows:
                    if arrow not in first_group:
                        arrow.should_highlight = True
                        arrow.highlight_timer = HIGHLIGHT_DURATION * 60
        # 自动移动触发
        if self.highlight_phase >= 1 and not self.auto_move_triggered:
            self.auto_move_timer -= 1
            if self.auto_move_timer <= 0:
                self._trigger_auto_move()
                self.auto_move_triggered = True

        # 箭头状态更新
        for arrow in self.arrows:
            if arrow.should_highlight:
                arrow.highlight_timer -= 1
                if arrow.highlight_timer <= 0:
                    arrow.should_highlight = False

        for event in pygame.event.get():
            if event.type == pygame.USEREVENT:
                # 显示第二组箭头
                first_group = self._select_one_per_direction()
                for arrow in self.arrows:
                    if arrow not in first_group:
                        arrow.start_highlight(HIGHLIGHT_DURATION)
                pygame.time.set_timer(pygame.USEREVENT, 0)  # 清除定时器

        for arrow in self.arrows:
            arrow.update(MOVE_SPEEDS['base'])  # 传递统一速度参数

    def _trigger_auto_move(self):
        """执行自动移动（与按F键相同效果）"""
        for arrow in self.arrows:
            arrow.start_movement()

    def draw(self):
        """绘制所有游戏元素"""
        # 清屏
        self.screen.fill(BACKGROUND_COLOR)

        # 1. 先绘制黄圈（最底层）
        pygame.draw.circle(
            self.screen, (0, 0, 0),
            (WIDTH // 2, HEIGHT // 2),
            YELLOW_CIRCLE_RADIUS + 2
        )
        pygame.draw.circle(
            self.screen, (200, 200, 0),
            (WIDTH // 2, HEIGHT // 2),
            YELLOW_CIRCLE_RADIUS
        )

        # 2. 绘制8个方位红点（在黄圈上方）
        for i in range(8):
            angle = math.radians(i * 45)
            pygame.draw.circle(
                self.screen, (255, 0, 0),
                (
                    int(WIDTH // 2 + RED_CIRCLE_POSITION_RADIUS * math.cos(angle)),
                    int(HEIGHT // 2 + RED_CIRCLE_POSITION_RADIUS * math.sin(angle))
                ),
                RED_CIRCLE_RADIUS
            )

        # 3. 绘制备选位置（在红点上方）
        # self.draw_candidates()

        # 4. 最后绘制所有箭头（最上层）
        for arrow in self.arrows:
            arrow.draw(self.screen)

        if self.fail_message:
            text = self.font.render(
                self.fail_message,
                True,
                FONT_CONFIG['color']
            )
            self.screen.blit(text, (20, 20))

        pygame.display.flip()

        if self.result_message:
            # 渲染文字（带黑色描边增强可视性）
            text_surface = self.font.render(self.result_message, True, self.result_color)

            # 描边效果
            border = 2
            pos = (20, 20)
            for dx, dy in [(border, 0), (-border, 0), (0, border), (0, -border)]:
                outline = self.font.render(self.result_message, True, (0, 0, 0))
                self.screen.blit(outline, (pos[0] + dx, pos[1] + dy))

            # 主体文字
            self.screen.blit(text_surface, pos)

        pygame.display.flip()

    def run(self):
        """主游戏循环"""
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(60)
